import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class MyThreadPool {

//    //1.线程什么时候创建
//    //2.线程的runnable是什么？需要我们提交command吗
//    BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(1024);
//
//    Thread thread = new Thread(() -> {
//        while(true){
//            try{
//                Runnable c = blockingQueue.take();
//                c.run();
//            }
//            catch(Exception e){
//                e.printStackTrace();
//            }
//        }
//    }, "唯一线程");
//
//    {
//        thread.start();
//    }
//
//    void execute(Runnable command)
//    {
//        boolean offer = blockingQueue.offer(command);
//
//    }

    BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(1024);
    //核心线程数
    private  int corePoolSize;
    //最大线程数
    private  int maximumPoolSize;
    //
    private int timeout;
    private TimeUnit timeunit;
    List<Thread> coreList = new ArrayList<>();
    List<Thread> supportList = new ArrayList<>();
    private final RejectHandle rejectHandle;
    private volatile boolean isShutdown = false;

    public MyThreadPool(int corePoolSize, int maximumPoolSize, int timeout, TimeUnit timeunit, BlockingQueue<Runnable> blockingQueue, RejectHandle rejectHandle)
    {
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.timeout = timeout;
        this.timeunit = timeunit;
        this.blockingQueue = blockingQueue;
        this.rejectHandle = rejectHandle;
    }

//    private final Runnable coreTask = () -> {
//        while(true){
//            try{
//                Runnable c = blockingQueue.take();
//                c.run();
//            }
//            catch(Exception e){
//                e.printStackTrace();
//            }
//        }
//    };
//
//    private final Runnable supportTask = () -> {
//        while(true){
//            try{
//                Runnable c = blockingQueue.poll(1, TimeUnit.SECONDS);
//                if(c == null) break;
//                c.run();
//            }
//            catch(Exception e){
//                e.printStackTrace();
//            }
//        }
//        System.out.println("supportTask 线程结束");
//    };


    void execute(Runnable command)
    {
        if (isShutdown) {
            throw new IllegalStateException("ThreadPool is shutdown");
        }
        // 1. 如果核心线程未满，创建核心线程
        if(coreList.size() < corePoolSize){
            Thread thread = new CoreThread();
            coreList.add(thread);
            thread.start();
        }
        // 2. 尝试将任务放入队列
        boolean offer = blockingQueue.offer(command);
        if(offer){
            return;
        }
        //// 3. 如果队列已满且线程数未达最大值，创建临时线程
        if(coreList.size() + supportList.size() < maximumPoolSize){
                Thread thread = new SupportThread();
                thread.start();
                supportList.add(thread);
            }
        //4. 触发拒绝策略
        if(!blockingQueue.offer(command)){
            //throw new RuntimeException("阻塞线程池已满");
            //添加拒绝策略
            rejectHandle.reject(command, this);
        }

    }
    //添加一个shutdown退出
    public void shutdown() {
        isShutdown = true;
        coreList.forEach(Thread::interrupt);
        supportList.forEach(Thread::interrupt);
    }

    class CoreThread extends Thread{
        @Override
        public void run()
        {
            while(!isShutdown){
                try{
                    //核心线程使用take()会阻塞等待新任务
                    Runnable c = blockingQueue.take();
                    c.run();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
    class SupportThread extends Thread{
        @Override
        public void run()
        {
            while(!isShutdown){
                try{
                    //非核心线程使用poll()会阻塞等待新任务，带超时时间的非永久阻塞
                    Runnable c = blockingQueue.poll(timeout, timeunit);
                    if(c == null) break;
                    c.run();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
            supportList.remove(this); // 移除已退出的线程
            System.out.println("supportTask 线程结束");
        }
    }
}
